home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1999 March
/
EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso
/
earcd
/
devel
/
vbcc-68k-src
/
machines
/
amiga68k
/
libsrc
/
math
/
math_040
/
acos.s
next >
Wrap
Text File
|
1999-01-01
|
4KB
|
101 lines
*
* $VER: acos.s 33.1 (22.1.97)
*
* Calculates the arccosine of the source
*
* Version history:
*
* 33.1 22.1.97 (c) Motorola
*
* - snipped from M68060SP sources
*
machine 68040
fpu 1
XDEF _acos
XDEF @acos
XREF @atan
*************************************************************************
* acos(): computes the inverse cosine of a normalized input *
* *
* INPUT *************************************************************** *
* fp0 = extended precision input *
* *
* OUTPUT ************************************************************** *
* fp0 = arccos(X) *
* *
* ACCURACY and MONOTONICITY ******************************************* *
* The returned result is within 3 ulps in 64 significant bit, *
* i.e. within 0.5001 ulp to 53 bits if the result is subsequently *
* rounded to double precision. The result is provably monotonic *
* in double precision. *
* *
* ALGORITHM *********************************************************** *
* *
* ACOS *
* 1. If |X| >= 1, go to 3. *
* *
* 2. (|X| < 1) Calculate acos(X) by *
* z := (1-X) / (1+X) *
* acos(X) = 2 * atan( sqrt(z) ). *
* Exit. *
* *
* 3. If |X| > 1, go to 5. *
* *
* 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. *
* *
* 5. (|X| > 1) Generate an invalid operation by 0 * infinity. *
* Exit. *
* *
*************************************************************************
PI dc.l $40000000,$C90FDAA2,$2168C235,$00000000
_acos
fmove.d (4,sp),fp0
@acos
fmove.x fp0,-(sp)
move.l (sp),d1 ; pack exp w/ upper 16 fraction
move.w (4,sp),d1
and.l #$7FFFFFFF,d1
cmp.l #$3FFF8000,d1
bge.b .ACOSBIG
;--THIS IS THE USUAL CASE, |X| < 1
;--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) )
.ACOSMAIN
lea (12,sp),sp
fmove.s #$3F800000,fp1
fadd.x fp0,fp1 ; 1+X
fneg.x fp0 ; -X
fadd.s #$3F800000,fp0 ; 1-X
fdiv.x fp1,fp0 ; (1-X)/(1+X)
fsqrt.x fp0 ; SQRT((1-X)/(1+X))
jsr @atan ; ATAN(SQRT([1-X]/[1+X]))
fadd.x fp0,fp0 ; 2 * ATAN( STUFF )
rts
.ACOSBIG
fabs.x fp0
fcmp.s #$3f800000,fp0
fbgt .operr
;--|X| = 1, ACOS(X) = 0 OR PI
tst.b (sp) ; is X positive or negative?
bpl.b .ACOSP1
;--X = -1
;Returns PI and inexact exception
.ACOSM1
fmove.x (PI,pc),fp0 ; load PI
.operr lea (12,sp),sp
rts
.ACOSP1 fmove.s #0,fp0
lea (12,sp),sp
rts